iT邦幫忙

2026 iThome 鐵人賽

DAY 17
0
AI 自動化

用 AI Agent 打造你的產品使用手冊產線系列 第 17

[Day 17] 自動組裝產線 2:實際讓 AI Agent 寫一章

  • 分享至 

  • xImage
  •  

昨天把交給 agent 之前該準備的東西都講完了:probe / validate / run --chapter 三個指令,加上 TESTID.mdUI-MAP.mdQUIRKS.mdschema.json 四份上下文。

今天把這套東西實際跑一次。

本日任務

範例專案 auto-manual-gen 的 manifest 目前有四章 (overview / live-monitor / layout-preset / settings),任務是加第五章:說明怎麼新增一台攝影機。

丟給 agent 的任務大致是這樣:

讀 apps/demo-stream-app/TESTID.md、agent/UI-MAP.md、agent/QUIRKS.md、
manifest/schema.json,以及 manifest/20-live-monitor.yaml 當格式範例。

新增一章 manifest/50-camera-add.yaml(id: camera-add, order: 50),
說明「如何新增一台攝影機」。需要探勘畫面就用 npm run probe,
寫完先跑 npm run validate,再跑 npm run manual -- --chapter camera-add --mode web。
兩個指令都過了再停,不要改 runner/ 底下任何檔案。

(只要大方向差不多,prompt 怎麼下應該影響不大)

最後那句話是重要的,要明確劃出 agent 可以動的範圍。它的工作是產出設定檔,不是在腳本跑不過的時候回頭改產線。

第一版設定檔與截圖

Day 16 說過這個迴圈長什麼樣子:探勘 → 寫一章 → validaterun --chapter → 失敗就讀錯誤訊息修、再跑一次。這中間 agent 確實被擋下來過幾次,但那些訊息是寫給 agent 看的,不是寫給人看的,人類只要看最後的新檔案就好。

進到 review 的,是這樣一份新檔案:

# manifest/50-camera-add.yaml(新檔案)
id: camera-add
title: 新增攝影機
order: 50

steps:
  - { action: waitFor, testid: camera-list-skeleton, state: detached }
  - { action: waitFor, testid: camera-list }

  - { action: click, testid: camera-add }
  - { action: waitFor, testid: camera-dialog }

  - action: screenshot
    name: camera-add-01
    clip: { testid: camera-dialog, padding: 12 }
    annotate:
      - { key: name, testid: camera-dialog-name, legend: 顯示名稱 }
      - { key: zone, testid: camera-dialog-zone, legend: 安裝位置 }
      - { key: source, testid: camera-dialog-source, legend: 串流位址 }
      - { key: enabled, testid: camera-dialog-enabled, legend: 啟用推論 }

  - { action: fill, testid: camera-dialog-name, text: 大門西側 }

  - action: screenshot
    name: camera-add-02
    clip: { testid: camera-dialog, padding: 12 }
    annotate:
      - { key: confirm, testid: camera-dialog-confirm, legend: 確認新增 }

兩張截圖是真的拍出來的:

camera-add-01:新增攝影機對話框,標註四個欄位

camera-add-02:填完顯示名稱,確認鍵從 disabled 變成可按

這其實就是 Day 14 選宣告式設定檔的好處:新增一章就是新增一個 yaml 檔案,不動到任何既有內容,review 的人看兩張圖跟二十幾行 YAML 就能判斷這一章對不對。如果當初走的是「請 AI 寫一支 TypeScript 腳本」,這裡要 review 的會是一份幾百行、跟舊版看不出關係的新腳本。

人工審查

機器已經確認過「動詞合法、selector 找得到、圖拍得出來」,所以 review 的重點只剩下機器判斷不了的部分。

不知道大家對於上面的範例有沒有覺得有什麼可以優化的地方?

其實已經挺好了,我覺得只有兩個很小的細節想微調:

  1. 操作順序不夠真實

    腳本能跑,不代表這是使用者真的會走的流程。這一章只填了顯示名稱就示範送出,RTSP 位址那欄其實只是 placeholder 而已,不是實際填入的值。雖然能跑,但真實情境裡新增一台攝影機至少該連同 RTSP 位址一起填,不然可能會有讀者以為那樣就算設定完成了。

  2. legend 的用詞跟畫面上的字不一致

    manifest 裡 source 欄位標的是「串流位址」,但對話框上寫的其實是「RTSP 位址」。AI agent 有時候會「順手把文案換一個說法」,這件事在撰寫正文時會變成一個嚴重的問題。

這兩件事都不是加幾條規則就能自動判斷的,它們需要的是「知道這個產品怎麼被使用、畫面上實際寫的是什麼字」,那是人才有的上下文。於是又丟了第二個 prompt 回去:

review 了 manifest/50-camera-add.yaml 的截圖,兩點要改:
1. source 欄位的 legend 改成「RTSP 位址」,跟畫面上的字對齊
2. 新增流程除了填顯示名稱,也要示範填 RTSP 位址,
   並且實際按下確認鍵、等 toast 出現後再多拍一張,
   讓這一章示範完整跑完一次新增流程長什麼樣子

改完重跑 npm run manual -- --chapter camera-add --mode web。

第二版設定檔與截圖

改動只有這幾行:

       - { key: name, testid: camera-dialog-name, legend: 顯示名稱 }
       - { key: zone, testid: camera-dialog-zone, legend: 安裝位置 }
-      - { key: source, testid: camera-dialog-source, legend: 串流位址 }
+      - { key: source, testid: camera-dialog-source, legend: RTSP 位址 }
       - { key: enabled, testid: camera-dialog-enabled, legend: 啟用推論 }

   - { action: fill, testid: camera-dialog-name, text: 大門西側 }
+  - { action: fill, testid: camera-dialog-source, text: 'rtsp://10.0.4.115/live' }

   - action: screenshot
     name: camera-add-02
     clip: { testid: camera-dialog, padding: 12 }
     annotate:
       - { key: confirm, testid: camera-dialog-confirm, legend: 確認新增 }
+
+  - { action: click, testid: camera-dialog-confirm }
+  - { action: waitFor, testid: toast }
+
+  - action: screenshot
+    name: camera-add-03
+    clip: { testid: toast-host, padding: 12 }

重跑之後,第一張圖其實沒變,畢竟 legend 只是 metadata,annotate 畫的是編號圓標,不會把文字印到圖上,所以「串流位址」改成「RTSP 位址」這件事只會出現在 YAML diff 裡,圖片本身看不出差異。真正有變化的是第二張,以及多了第三張:

camera-add-02(微調後):RTSP 位址也一起填了

camera-add-03:按下確認鍵後,等 toast 出現立刻拍下

第三張圖能穩定拍到,靠的是 Day 15 就寫進 QUIRKS.md 的那條規則:toast 3 秒後自動消失,waitFor: toast 抓到語意訊號就立刻按快門,不要在中間插入其他等待。這條規則沒寫進上下文的話,agent 大概率會用固定延遲賭時間,直到後面去翻程式碼才發現問題。

指令

如果各位想自己試試看,可以把範例專案 clone 下來、切到 chore/day17 分支就能重現這兩個版本。人工審查前微調後各留了一個 tag,對應文章裡的兩組截圖:

npm run demo      # 另開一個終端機,Web 模式跑起來

# agent 的第一版:只示範填顯示名稱
git checkout day17-agent-v1 -- manifest/50-camera-add.yaml
npm run validate -- --chapter camera-add
npm run manual -- --chapter camera-add --mode web   # 產出 camera-add-01 / -02

# 人工審查後微調:補 RTSP 位址、修正 legend、示範按下確認鍵
git checkout day17 -- manifest/50-camera-add.yaml
npm run manual -- --chapter camera-add --mode web   # 多出 camera-add-03

probe 也是這次順便補上的,想看 agent 探勘畫面時看到的東西長什麼樣,直接試:

npm run probe -- --mode web --after click:camera-add

如果想換一章比較硬的自己試試看,可以換成「刪除一台攝影機」——那一章會遇到巢狀對話框(刪除確認框疊在攝影機對話框之上),也會遇到刪除按鈕只在編輯模式才存在的問題,QUIRKS.md 裡都寫了,但沒實際跑一次很難有感覺。

經驗分享

1. agent 會發明不存在的 testid

這是最常見的幻覺形式。即使給了完整清單,它還是可能「猜」出一個聽起來很合理、實際不存在的 testid (e.g. 確認鍵被猜成 camera-dialog-save)。

防範方式是兩層都要有:validate 擋格式,run 擋存在性。只靠其中一層都會漏,schema 不知道畫面上有什麼,而 runner 要等到開機才知道。

2. 一次一章,不要一次產一整本

很容易想直接說「幫我把整本手冊的 manifest 寫出來」,但這樣做有兩個問題:失敗的時候不知道是哪一章壞了,而且 review 的人要一次面對二、三十個新檔案。

一次一章,每一章都走完「產出 → 驗證 → 實跑 → review」,錯誤才不會累積。這跟 Day 15 把重跑單位設計成「一章」是同一個理由。

3. 真正花時間的不是 agent,是補上下文

實際做下來,UI-MAP.mdQUIRKS.md 這幾份文件花掉的時間,比 agent 產出設定檔的時間多得多。

但這個成本只付一次,而且下一章、下一次改版、甚至新人進來都還在用。相對地,如果省掉這一步,省下的時間會以「agent 每一章都猜錯、每一章都要人重看」的形式,逐漸還回去。

小結

今天這一章從頭到尾,AI agent 自己搞定一切,把設定檔寫出來了。人真正花時間做的,是機器判斷不了的那兩件事:操作順序像不像真人會做的事、文案用詞跟畫面對不對得上。看完、提出來、再丟回去微調一次,AI agent 就把它改好了。

不過,目前為止,AI 產出的還只是「怎麼拍」的設定檔,使用手冊還有同等重要的另一半:文字說明。這部分就明天接著討論啦!


上一篇
[Day 16] 自動組裝產線 1:準備讓 AI Agent 寫設定檔
系列文
用 AI Agent 打造你的產品使用手冊產線17
圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言